/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.helper;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.uml2.uml.Component;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;

import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.core.preference.ClassDiagramCommonPreferenceConstants;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;

/**
 * Factory that can create and delete an {@link org.eclipse.uml2.uml.Class}.
 * 
 * @author Patrick Tessier
 */
public class NodeClassHelper extends NodeHelper {

	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.factories.NodeFactory#createGraphElement(org.eclipse.uml2.uml.Element, com.cea.papyrus.diagraminterchange2.di2.GraphElement, org.eclipse.draw2d.geometry.Point, org.eclipse.draw2d.geometry.Dimension)
	 */
	@Override
	public GraphNode createGraphElement(Element umlChild, GraphElement parent, Point location, Dimension size){
		Debug.debug(this,"Call NodeClassFactory.createGraphNode()", channel); //$NON-NLS-1$
		
		// creates compartments for class figure (operation and attribute) 
		GraphNode graphNode=super.createGraphElement(umlChild, null, location, size);
		for (int i=0;i<2;i++){//Acha graphNode for each possible compartment
			GraphElement gN=super.createGraphElement(null,graphNode,null,null);
		}
		
		//the ge parent is connected in last becaus an event may be sent at this moment and trigger a refresh.
		if(parent != null) {
			parent.getContained().add(graphNode);
		}
		return graphNode;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.factories.NodeFactory#createGraphNode(org.eclipse.uml2.uml.NamedElement, com.cea.papyrus.diagraminterchange2.di2.Diagram)
	 */
	@Override
	public ArrayList createGraphNode(Element umlElement, Diagram diagram) {

		Debug.debug(this,"Call NodeClassFactory.createGraphNode()", channel);
		ArrayList createdNode =super.createGraphNode(umlElement, diagram);

		Iterator it =createdNode.iterator();
		while(it.hasNext()){
			//current node
			GraphNode currentNode=(GraphNode)it.next();
			currentNode.setSize(new Dimension(100,50));
			super.createGraphElement(null,currentNode,null,null);//properties
			super.createGraphElement(null,currentNode,null,null);//operations

			//currentNode.setPosition(new Point(20, 20));
		}
		return createdNode;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.factories.NodeFactory#canExecute(com.cea.papyrus.diagraminterchange2.di2.GraphNode)
	 */
	@Override
	public boolean canCreateGraphElement(GraphElement parent){
		if(parent instanceof Diagram) {
			return true;
		} else if (parent.getSemanticModel()!=null){
			Element parentElt= ((Uml1SemanticModelBridge)parent.getSemanticModel()).getElement();
			if(parentElt!=null){
				return canCreateUMLElement(parentElt);
			}
		}
		return false;
	}


    ///////////////////////////////////////////////////////////////////////////
    // UML Management
    ///////////////////////////////////////////////////////////////////////////
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.factories.NodeFactory#createElement(java.lang.String, org.eclipse.uml2.uml.Element)
	 */
    @Override
	public  org.eclipse.uml2.uml.Element createUMLElement(String name, org.eclipse.uml2.uml.Element umlParent){
    	Debug.debug(this,"Call NodeClassFactory.createClass()", channel); //$NON-NLS-1$
		org.eclipse.uml2.uml.Class umlClass; //= ((Package)umlParent).createOwnedClass(name, false);
		if (umlParent instanceof Component) {
			umlClass=((Component)umlParent).createOwnedClass(name, false);
			return umlClass;
			} 
		//umlParent instanceof Package) 
			umlClass=((Package)umlParent).createOwnedClass(name, false);
			return umlClass;

				//else should throw new UMLException;
				//return umlClass;		
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.factories.NodeFactory#canExecuteCreateElement(org.eclipse.uml2.uml.Element)
	 */
	@Override
	public boolean canCreateUMLElement(Element umlParent) {
		// Added by A. Lanusse for adding elt into component
		if(umlParent instanceof Component || umlParent instanceof Package) {
			return true;
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.factories.NodeFactory#addElement(org.eclipse.uml2.uml.Element, org.eclipse.uml2.uml.Element)
	 */
	@Override
	public boolean addUMLElement(Element element, Element umlParent) {
		// Added by A. Lanusse for adding elt into component
		if(umlParent instanceof Component) {
			return ((org.eclipse.uml2.uml.Component)umlParent).getPackagedElements().add((PackageableElement)element);
		}
		if(umlParent instanceof Package) {
			return ((Package)umlParent).getPackagedElements().add((PackageableElement)element);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.factories.NodeFactory#removeElement(org.eclipse.uml2.uml.Element, org.eclipse.uml2.uml.Element)
	 */
	@Override
	public boolean removeUMLElement(Element element, Element umlParent) {
		// Added by A. Lanusse for removing elt from component
		if(umlParent instanceof Component) {
			return ((org.eclipse.uml2.uml.Component)umlParent).getPackagedElements().remove(element);
		}
		if(umlParent instanceof Package) {
			return ((Package)umlParent).getPackagedElements().remove(element);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.factories.NodeFactory#getBaseString()
	 */
	@Override
	public String getBaseString() {
		return "Class_"; //$NON-NLS-1$
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.common.helper.NodeHelper#setGraphElementPreferences(com.cea.papyrus.diagraminterchange2.di2.GraphElement)
	 */
	@Override
	public void setGraphElementPreferences(GraphElement graphElement) {
//		 Get the preference store
		IPreferenceStore store = PapyrusPlugin.getDefault().getPreferenceStore();
		
		// Set colors and font
		graphElement.setBackgroundColor(ClassDiagramCommonPreferenceConstants.getPreferenceClassBackgroundColor(store));
		graphElement.setBorderColor(ClassDiagramCommonPreferenceConstants.getPreferenceClassBorderColor(store));
		graphElement.setFontColor(ClassDiagramCommonPreferenceConstants.getPreferenceClassFontColor(store));
		FontData[] fontdata = ClassDiagramCommonPreferenceConstants.getPreferenceClassFont(store);
		if (fontdata.length>0){
			graphElement.setFontFamily(fontdata[0].getName());
			graphElement.setFontSize(fontdata[0].getHeight());
		}
	}
}
